import os
import time
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# 导入依赖分析模块
from mach_o_dependency_analyzer import analyze_mach_o_dependencies

class AppBundleMonitor(FileSystemEventHandler):
    def __init__(self, target_dir, app_name=None):
        self.target_dir = target_dir
        self.app_name = app_name  # 指定要匹配的app名称
        self.processed = set()  # 用于去重处理

    def on_created(self, event):
        # 只处理根目录下的文件夹创建事件
        if not event.is_directory:
            return
            
        path = event.src_path
        # 确保是直接位于根目录下的文件夹
        if os.path.dirname(path) != self.target_dir:
            return
            
        # 延迟一小段时间确保文件完全写入
        time.sleep(0.5)
        print(f"检测到新文件夹: {path}")
        
        # 立即扫描新文件夹中的.app文件夹
        for item in os.listdir(path):
            item_path = os.path.join(path, item)
            if item.endswith('.app') and os.path.isdir(item_path):
                print(f"发现应用目录: {item_path}")
                self._check_and_print_app(item_path)
                return

    def _check_and_print_app(self, app_path):
        """检查app路径是否匹配指定名称并打印"""
        if not os.path.isdir(app_path) or app_path in self.processed:
            return
            
        # 获取app文件夹名称
        app_name = os.path.basename(app_path)
        
        # 如果没有指定app名称或者名称匹配，则打印并退出
        if self.app_name is None or self.app_name in app_name:
            print(f"找到应用: {app_name}")
            
            # 创建outputs目录
            output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'outputs')
            os.makedirs(output_dir, exist_ok=True)
            
            # 生成输出文件路径
            output_file = os.path.join(output_dir, f"{app_name.replace('.app', '')}_dependency.html")
            
            self.processed.add(app_path)
            # 增加1秒延迟
            time.sleep(1)
            print(f"开始分析应用: app_path={app_path},output_file={output_file},app_name={app_path + "/" + app_name.replace(".app", "")}")
            analyze_mach_o_dependencies(app_path, output_file, app_path + "/" + app_name.replace(".app", ""))
            # 找到目标应用后退出程序
            os._exit(0)

    def check_app_bundle(self, parent_path, depth=0):
        """递归扫描目录中的.app文件夹，最大深度为2"""
        if depth > 1:  # 限制递归深度为2
            return
            
        print(f"开始扫描目录(深度{depth}): {parent_path}")
        # 添加目录存在性检查
        if not os.path.exists(parent_path) or not os.path.isdir(parent_path):
            print(f"警告: 目录不存在或已被删除 - {parent_path}")
            return
            
        # 检查当前目录中的.app文件夹
        for item in os.listdir(parent_path):
            item_path = os.path.join(parent_path, item)
            if item.endswith('.app') and os.path.isdir(item_path):
                print(f"发现应用目录: {item_path}")
                self._check_and_print_app(item_path)
                return
            elif os.path.isdir(item_path):
                # 递归检查子目录
                self.check_app_bundle(item_path, depth + 1)

    def on_modified(self, event):
        # 有些文件系统操作可能触发修改而不是创建事件
        if event.is_directory:
            path = event.src_path
            print(f"检测到目录修改: {path}")
            # 检查是否是.app目录
            if path.endswith('.app'):
                self._check_and_print_app(path)
            else:
                # 延迟一点时间再检查，确保文件写入完成
                time.sleep(0.5)
                self.check_app_bundle(path)

    # 移除不再需要的 check_app_bundle 方法
    # 移除不再需要的 on_modified 方法

def monitor_folder(path, app_name=None):
    event_handler = AppBundleMonitor(path, app_name)
    observer = Observer()
    # 关闭递归监控，只监控根目录
    observer.schedule(event_handler, path, recursive=False)
    observer.start()
    
    try:
        if app_name:
            print(f"开始监控文件夹: {path}，查找应用: {app_name}")
        else:
            print(f"开始监控文件夹: {path}，查找所有.app应用(仅限根目录下的新文件夹内)")
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

if __name__ == "__main__":
    # 获取命令行参数
    if len(sys.argv) < 2:
        print("用法: python app_monitor.py <目标目录> [应用名称]")
        print("错误: 必须指定目标目录")
        sys.exit(1)
    
    target_directory = sys.argv[1]
    app_name = sys.argv[2] if len(sys.argv) > 2 else None
    
    if not os.path.exists(target_directory):
        print(f"错误: 目录不存在 - {target_directory}")
        sys.exit(1)
    
    if not os.path.isdir(target_directory):
        print(f"错误: 不是有效的目录 - {target_directory}")
        sys.exit(1)
    
    monitor_folder(target_directory, app_name)